package vn.com.vega.chacha.v2;

import java.io.IOException;
import java.lang.ref.WeakReference;
import java.util.List;

import vn.com.vega.chacha.R;
import vn.com.vega.music.clientserver.JsonWatchUrl;
import vn.com.vega.music.objects.Video;
import vn.com.vega.music.utils.Util;
import android.annotation.SuppressLint;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.media.AudioManager;
import android.media.AudioManager.OnAudioFocusChangeListener;
import android.media.MediaPlayer;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.view.WindowManager;
import android.widget.ImageButton;
import android.widget.ProgressBar;
import android.widget.SeekBar;
import android.widget.TextView;

public class VideoPlayerScreen extends ActivityBase implements
		SurfaceHolder.Callback, OnClickListener {
	public static final String INDEX_VIDEO = "index video";
	public static final String VIDEO_LIST_NAME = "Name list video play";

	private static final int UPDATE_CURRENT_TIME = 1;
	private static final int AUTO_HIDE_CONTROL = 2;

	private static final int TIME_AUTO_HIDE = 2000;

	private static final String TAG_STRING = VideoPlayerScreen.class
			.getSimpleName();

	private SurfaceView mSurfaceView;
	private SurfaceHolder mHolder;
	private ProgressBar mProgressBar;
	private ImageButton mPlayPauseBtn;
	private TextView mCurrentTime;
	private TextView mTotalTime;
	private SeekBar mSeekBar;
	private MediaPlayer mVideoPlayer;
	private Video queue;
	boolean prePareDone = true;
	private int indextCurrentVideo;
	private List<Video> listVideos;
	private Appinstant mApp;
	private boolean isPause = false;
	private PrepareVideoPlayer prepareVideoPlayer;
	private AudioManager audioManager;

	@Override
	protected void onCreate(Bundle arg0) {
		// TODO Auto-generated method stub
		super.onCreate(arg0);
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
		mApp = (Appinstant) getApplication();
		setContentView(R.layout.video_player_screen);
		mPlayPauseBtn = (ImageButton) findViewById(R.id.bt_play_pause);
		mProgressBar = (ProgressBar) findViewById(R.id.progressbar_loading_video);
		mSeekBar = (SeekBar) findViewById(R.id.seekBar);
		mSeekBar.setOnSeekBarChangeListener(onSeekBarChangeListener);
		mCurrentTime = (TextView) findViewById(R.id.tv_current_duration);
		mTotalTime = (TextView) findViewById(R.id.tv_total_duration);
		mSurfaceView = (SurfaceView) findViewById(R.id.surface_view_video);
		mSurfaceView.setOnClickListener(this);
		mHolder = mSurfaceView.getHolder();
		mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
		mHolder.addCallback(this);
		Intent startIntent = getIntent();
		indextCurrentVideo = startIntent.getIntExtra(INDEX_VIDEO, -1);
		String listVideoNameString = startIntent
				.getStringExtra(VIDEO_LIST_NAME);
		listVideos = mApp.tranportListVideo.remove(listVideoNameString);
		mPlayPauseBtn.setOnClickListener(this);
		audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
		
		IntentFilter intentFilter = new IntentFilter();
		intentFilter.addAction(CMD_DO_NOT_PLAY_VIDEO);
		intentFilter.addAction(CMD_PLAY_VIDEO);
		registerReceiver(broadcastReceiver, intentFilter);
	}

	private void initVideoPlayer(Video video) {
		if (video == null) {
			return;
		}

		if (!prePareDone) {
			queue = video;
			return;
		}
		releasePlayer();
		mVideoPlayer = new MediaPlayer();
		mVideoPlayer.setScreenOnWhilePlaying(true);
		mVideoPlayer.setDisplay(mHolder);
		mVideoPlayer.setOnCompletionListener(onCompletionListener);
		mVideoPlayer.setOnErrorListener(onErrorListener);
		mVideoPlayer.setOnPreparedListener(onPreparedListener);
		mVideoPlayer.setOnBufferingUpdateListener(onBufferingUpdateListener);

		if (video.isDownloaded()) {
			try {
				mVideoPlayer.setDataSource(video.cached_file_path);
				mVideoPlayer.prepareAsync();
			} catch (Exception e) {
				// TODO: handle exception
			}
		} else {
			JsonWatchUrl jsonWatchUrl = JsonWatchUrl.loadWatchUrl(Integer
					.valueOf(video.id));
			if (jsonWatchUrl.isSuccess()) {
				String videoUrl = jsonWatchUrl.streamingUrl;
				try {
					mVideoPlayer.setDataSource(videoUrl);
					mVideoPlayer.prepareAsync();
				} catch (IllegalArgumentException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (SecurityException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (IllegalStateException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}

	}

	static class PrepareVideoPlayer extends AsyncTask<Void, Void, Void> {
		Video video;
		WeakReference<VideoPlayerScreen> videoPlayerReference;

		public PrepareVideoPlayer(Video video,
				VideoPlayerScreen videoPlayerScreen) {
			this.video = video;
			videoPlayerReference = new WeakReference<VideoPlayerScreen>(
					videoPlayerScreen);
		}

		private boolean checkIsLive() {
			VideoPlayerScreen videoPlayerScreen = videoPlayerReference.get();
			if (videoPlayerScreen == null || videoPlayerScreen.isDestroy) {
				return false;
			}
			return true;
		}

		@Override
		protected Void doInBackground(Void... params) {
			// TODO Auto-generated method stub
			if (!checkIsLive()) {
				return null;
			}
			VideoPlayerScreen videoPlayerScreen = videoPlayerReference.get();
			videoPlayerScreen.trackEvent(Category.selectItem, Action.playVideo,
					video.title, 1);
			videoPlayerScreen.initVideoPlayer(video);
			return null;
		}

		@Override
		protected void onPreExecute() {
			// TODO Auto-generated method stub
			super.onPreExecute();
			if (isCancelled() || !checkIsLive()) {
				return;
			}
			VideoPlayerScreen videoPlayerScreen = videoPlayerReference.get();
			videoPlayerScreen.mHandler.removeCallbacksAndMessages(null);
			videoPlayerScreen.mCurrentTime.setText("00:00");
			videoPlayerScreen.mTotalTime.setText("00:00");
			videoPlayerScreen.mSeekBar.setProgress(0);
			videoPlayerScreen.mPlayPauseBtn.setSelected(true);
			videoPlayerScreen.mPlayPauseBtn.setVisibility(View.GONE);
			videoPlayerScreen.mProgressBar.setVisibility(View.VISIBLE);
		}

	}

	MediaPlayer.OnCompletionListener onCompletionListener = new MediaPlayer.OnCompletionListener() {

		@SuppressLint("NewApi")
		@Override
		public void onCompletion(MediaPlayer mp) {
			// TODO Auto-generated method stub
			// if (Build.VERSION.SDK_INT >= 8) {
			// audioManager.abandonAudioFocus(audioFocusChangeListener);
			// }
			finish();
		}
	};
	OnAudioFocusChangeListener audioFocusChangeListener = new OnAudioFocusChangeListener() {

		@Override
		public void onAudioFocusChange(int focusChange) {
			// TODO Auto-generated method stub
			if (focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT) {
				// Pause playback
				pauseVideo();
			} else if (focusChange == AudioManager.AUDIOFOCUS_GAIN) {
				// Do nothing, because playvideo not audio.
			} else if (focusChange == AudioManager.AUDIOFOCUS_LOSS) {
				// am.unregisterMediaButtonEventReceiver(RemoteControlReceiver);
				// Stop playback
				releasePlayer();
			}
		}
	};

	MediaPlayer.OnPreparedListener onPreparedListener = new MediaPlayer.OnPreparedListener() {

		@SuppressLint("NewApi")
		@Override
		public void onPrepared(MediaPlayer mp) {
			// TODO Auto-generated method stub
			prePareDone = true;
			mProgressBar.setVisibility(View.GONE);
			mPlayPauseBtn.setVisibility(View.VISIBLE);
			int totalTime = getTotalTime() / 1000;
			mTotalTime.setText(Util.intToStringTimeFormat(totalTime));
			mSeekBar.setMax(totalTime);
			if (!isPause) {
				if (Build.VERSION.SDK_INT >= 8) {
					audioManager.requestAudioFocus(audioFocusChangeListener,
					// Use the music stream.
							AudioManager.STREAM_MUSIC,
							// Request permanent focus.
							AudioManager.AUDIOFOCUS_GAIN);
				}

				mVideoPlayer.start();
				mPlayPauseBtn.setSelected(false);
				mHandler.sendEmptyMessage(UPDATE_CURRENT_TIME);
				mHandler.sendEmptyMessageDelayed(AUTO_HIDE_CONTROL,
						TIME_AUTO_HIDE);
			}
		}
	};

	MediaPlayer.OnBufferingUpdateListener onBufferingUpdateListener = new MediaPlayer.OnBufferingUpdateListener() {

		@Override
		public void onBufferingUpdate(MediaPlayer mp, int percent) {
			// TODO Auto-generated method stub

		}
	};

	MediaPlayer.OnErrorListener onErrorListener = new MediaPlayer.OnErrorListener() {

		@Override
		public boolean onError(MediaPlayer mp, int what, int extra) {
			// TODO Auto-generated method stub
			return false;
		}
	};

	private UpdatePlayerInfo mHandler = new UpdatePlayerInfo(this);

	static class UpdatePlayerInfo extends Handler {
		WeakReference<VideoPlayerScreen> videoPlayerScreenRfc;

		public UpdatePlayerInfo(VideoPlayerScreen videoPlayerScreen) {
			videoPlayerScreenRfc = new WeakReference<VideoPlayerScreen>(
					videoPlayerScreen);
		}

		@Override
		public void handleMessage(Message msg) {
			VideoPlayerScreen videoPlayerScreen = videoPlayerScreenRfc.get();
			if (videoPlayerScreen == null || videoPlayerScreen.isDestroy) {
				removeCallbacksAndMessages(null);
				return;
			}
			switch (msg.what) {
			case UPDATE_CURRENT_TIME:
				int currentTime = videoPlayerScreen.getCurrentTime() / 1000;
				videoPlayerScreen.mCurrentTime.setText(Util
						.intToStringTimeFormat(currentTime));
				videoPlayerScreen.mSeekBar.setProgress(currentTime);
				sendEmptyMessageDelayed(UPDATE_CURRENT_TIME, 1000);
				break;
			case AUTO_HIDE_CONTROL:
				videoPlayerScreen.hideControl();
				break;
			case FINISH:
				videoPlayerScreen.finishAct();
				break;
			default:
				break;
			}
		}
	}

	private void finishAct() {
		super.finish();
	}

	private void showControl() {
		mPlayPauseBtn.setVisibility(View.VISIBLE);
		mCurrentTime.setVisibility(View.VISIBLE);
		mTotalTime.setVisibility(View.VISIBLE);
		mSeekBar.setVisibility(View.VISIBLE);
		mHandler.removeMessages(AUTO_HIDE_CONTROL);
		mHandler.sendEmptyMessageDelayed(UPDATE_CURRENT_TIME, TIME_AUTO_HIDE);
	}

	private void hideControl() {
		mHandler.removeMessages(AUTO_HIDE_CONTROL);
		mPlayPauseBtn.setVisibility(View.GONE);
		mCurrentTime.setVisibility(View.GONE);
		mTotalTime.setVisibility(View.GONE);
		mSeekBar.setVisibility(View.GONE);
	}

	private int getCurrentTime() {
		if (mVideoPlayer != null) {
			try {
				return mVideoPlayer.getCurrentPosition();
			} catch (Exception e) {
				// TODO: handle exception
			}
		}

		return 0;
	}

	private int getTotalTime() {
		if (mVideoPlayer != null) {
			try {
				return mVideoPlayer.getDuration();
			} catch (Exception e) {
				// TODO: handle exception
			}
		}

		return 0;
	}

	@Override
	protected void onResume() {
		// TODO Auto-generated method stub
		super.onResume();
		if (isPause) {
			playVideo();
		}
		isPause = false;
	}

	@Override
	protected void onPause() {
		// TODO Auto-generated method stub
		super.onPause();
		isPause = true;
		pauseVideo();
	}

	private void pauseVideo() {
		try {
			mPlayPauseBtn.setSelected(true);
			mHandler.removeCallbacksAndMessages(null);
			mVideoPlayer.pause();
		} catch (Exception e) {
			// TODO: handle exception
		}
	}

	private void playVideo() {
		try {
			mPlayPauseBtn.setSelected(false);
			mHandler.sendEmptyMessage(UPDATE_CURRENT_TIME);
			mHandler.sendEmptyMessageDelayed(AUTO_HIDE_CONTROL, TIME_AUTO_HIDE);
			mVideoPlayer.start();
		} catch (Exception e) {
			// TODO: handle exception
		}
	}

	@Override
	protected void onDestroy() {
		// TODO Auto-generated method stub
		try {
			unregisterReceiver(broadcastReceiver);
		} catch (Exception e) {
			// TODO: handle exception
		}
		prepareVideoPlayer.cancel(true);
		releasePlayer();
		super.onDestroy();
	}

	private void releasePlayer() {
		if (mVideoPlayer != null) {
			try {
				audioManager.abandonAudioFocus(audioFocusChangeListener);
				mVideoPlayer.release();
			} catch (Exception e) {
				// TODO: handle exception
			}
		}
	}

	public static final String CMD_PLAY_VIDEO = "vn.com.vega.chacha.playvideo";
	public static final String CMD_DO_NOT_PLAY_VIDEO = "vn.com.vega.chacha.donotplayvideo";

	private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {

		@Override
		public void onReceive(Context context, Intent intent) {
			// TODO Auto-generated method stub
			try {
				VideoPlayerScreen.this.unregisterReceiver(broadcastReceiver);
			} catch (Exception e) {
				// TODO: handle exception
			}
			String command = intent.getAction();
			if (CMD_DO_NOT_PLAY_VIDEO.equals(command)) {
				doInitPlayVideo();
			} else if (CMD_PLAY_VIDEO.equals(command)) {
				doNotPlayVideo();
			}
		}
	};

	private void doInitPlayVideo() {
		try {
			Video video = listVideos.get(indextCurrentVideo);
			// initVideoPlayer(video);
			if (prepareVideoPlayer != null) {
				prepareVideoPlayer.cancel(true);
			}
			prepareVideoPlayer = new PrepareVideoPlayer(video, this);
			prepareVideoPlayer.execute();

		} catch (Exception e) {
			// TODO: handle exception
		}
	}

	private void doNotPlayVideo() {
		finish();
	}

	@Override
	public void surfaceChanged(SurfaceHolder holder, int format, int width,
			int height) {
		// TODO Auto-generated method stub

	}

	@Override
	public void surfaceCreated(SurfaceHolder holder) {
		// TODO Auto-generated method stub
		Video video = listVideos.get(indextCurrentVideo);
		
//		if (Util.checkStringIsemptyOrNull(video.listenPrice)) {
//			doInitPlayVideo();
//		} else {
			Intent intent = new Intent(this, DialogConfirmPlaySong.class);
			intent.putExtra(DialogConfirmPlaySong.KEY_CONFIRM_TYPE, DialogConfirmPlaySong.CONFIRM_PLAY_VIDEO);
			intent.putExtra(DialogConfirmPlaySong.KEY_CONFIRM_MESSAGE, 
					"Bạn sẽ bì trừ " + video.listenPrice + " khi xem clip này.\n"
					+ Appinstant.warningMessage);
			intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TOP);
			startActivity(intent);
//		}

	}

	@Override
	public void surfaceDestroyed(SurfaceHolder holder) {
		// TODO Auto-generated method stub

	}

	@Override
	public void onClick(View v) {
		// TODO Auto-generated method stub
		switch (v.getId()) {
		case R.id.surface_view_video:
			if (mSeekBar.isShown()) {
				hideControl();
			} else {
				showControl();
				mHandler.sendEmptyMessageDelayed(AUTO_HIDE_CONTROL,
						TIME_AUTO_HIDE);
			}
			break;
		case R.id.bt_play_pause:
			try {
				if (mVideoPlayer.isPlaying()) {
					pauseVideo();
				} else {
					playVideo();
				}
			} catch (Exception e) {
				// TODO: handle exception
			}

		default:
			break;
		}
	}

	private static final int FINISH = 3;

	@Override
	public void finish() {
		// TODO Auto-generated method stub
		getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
		// Bug show main menu
		mHandler.sendEmptyMessageDelayed(FINISH, 50);
	}

	SeekBar.OnSeekBarChangeListener onSeekBarChangeListener = new SeekBar.OnSeekBarChangeListener() {

		@Override
		public void onStopTrackingTouch(SeekBar seekBar) {
			// TODO Auto-generated method stub
			mHandler.sendEmptyMessageDelayed(AUTO_HIDE_CONTROL, TIME_AUTO_HIDE);
		}

		@Override
		public void onStartTrackingTouch(SeekBar seekBar) {
			// TODO Auto-generated method stub
			mHandler.removeMessages(AUTO_HIDE_CONTROL);
		}

		@Override
		public void onProgressChanged(SeekBar seekBar, int progress,
				boolean fromUser) {
			// TODO Auto-generated method stub
			if (fromUser) {
				Video video = listVideos.get(indextCurrentVideo);
				if (video.isDownloaded()) {
					mVideoPlayer.seekTo(progress * 1000);
				}
			}
		}
	};

}
